<?php
/**
 * @create: IntelliJ IDEA
 * @detail:
 * @author: tom1@huolala.com
 * @date: 2022-03-21 15:47
 */

namespace App\Utils;


use Psr\Log\LoggerInterface;
use Symfony\Component\HttpClient\CurlHttpClient;

class LarkMessage
{
    const MESSAGE_TYPE_POST = 'post';
    const MESSAGE_TYPE_TEXT = 'text';
    const MESSAGE_TYPE_INTERACTIVE = 'interactive';
    const FEISHU_TENANT_TOKEN = 'feishu.tenant_token';
    const FEISHU_APP_TOKEN = 'feishu.app_token';


    private $client;

    private $appid;

    private $appsecret;

    /**
     * @var \Redis
     */
    private $redis;

    /**
     * @var LoggerInterface
     */
    private $logger;

    /**
     * @param $client
     */
    public function __construct($appid = null, $appsecret = null)
    {
        $this->appid = $appid;
        $this->appsecret = $appsecret;
    }

    /**
     * @param mixed $client
     */
    public function setClient($client): void
    {
        $this->client = $client;
    }

    /**
     * @return \Redis
     */
    public function getRedis(): \Redis
    {
        return $this->redis;
    }

    /**
     * @param \Redis $redis
     */
    public function setRedis(\Redis $redis): void
    {
        $this->redis = $redis;
    }

    /**
     * @return LoggerInterface
     */
    public function getLogger(): LoggerInterface
    {
        return $this->logger;
    }

    /**
     * @param LoggerInterface $logger
     */
    public function setLogger(LoggerInterface $logger): void
    {
        $this->logger = $logger;
    }


    /**
     * @param $msgType
     * @param $userObj
     * @param $content
     * @return false|mixed
     */
    public function sendFeishuMsgCommon($msgType, $userObj, $content)
    {
        // 获取token
        $token = $this->getTenantAccessToken();
        $url = 'https://open.feishu.cn/open-apis/message/v4/send/';
        $data = [
            'msg_type' => $msgType,
        ];
        if (in_array($msgType, [self::MESSAGE_TYPE_POST, self::MESSAGE_TYPE_TEXT])) {
            $data['content'] = $content;
        }
        if ($msgType == self::MESSAGE_TYPE_INTERACTIVE) {
            $data['card'] = $content;
        }
        $data = array_merge($data, $userObj);

        $options = [];
        $options['timeout'] = 5;
        $options['headers']['Content-Type'] = 'application/json';
        $options['headers']['Authorization'] = $this->generateAuthorization($token);
        $options['json'] = $data;

        $body = $this->request('POST', $url, $options);
        $body = json_decode($body, true);
        if (!empty($body) && $body['code'] == 0) {
            return $body['data'];
        }
        return false;
    }

    public function getTenantAccessToken()
    {
        // 获取缓存token
        $token = $this->redis->get(self::FEISHU_TENANT_TOKEN . $this->appid);
        if ($token) {
            return $token;
        }

        $url = 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal/';
        $data = [
            'app_id' => $this->appid,
            'app_secret' => $this->appsecret
        ];
        $options = [];
        $options['timeout'] = 5;
        $options['headers']['Content-Type'] = 'application/json';
        $options['json'] = $data;

        $body = $this->request('POST', $url, $options);
        $body = json_decode($body);
        if ($body && $body->code == 0) {
            $token = $body->tenant_access_token;
            $expire = $body->expire;
            // 缓存token
            $this->redis->setex(self::FEISHU_TENANT_TOKEN . $this->appid, (int)$expire, $token);
            return $token;
        }
        return '';
    }

    public function generateAuthorization($token)
    {
        return 'Bearer ' . $token;
    }

    public function getAndCacheChat()
    {
        switch (HLL_ENV) {
            case 'prd':
                $chat = $this->cacheChat('商城新增商品通知接收群');
                break;
            default:
                $chat = $this->cacheChat('创新业务部-程序报告群');
                break;
        }
        return $chat;
    }

    public function cacheChat($name)
    {
        // 获取缓存token
        $cacheChat = $this->redis->get('feishu_chat_id:' . $name);
        if ($cacheChat) {
            return json_decode($cacheChat, true);
        }
        $chat = $this->getChat($name);
        $this->debug("feishu_log", ['chat' => $chat]);
        if (!empty($chat)) {
            // 缓存token
            $this->redis->setex('feishu_chat_id:' . $name, 24 * 60 * 60 * 7, json_encode($chat));
            return $chat;
        }
    }

    private function debug($message, $context = [])
    {
        if ($this->logger) {
            $this->logger->debug($message, $context);
        }
    }


    public function getAppAccessToken()
    {
        // 获取缓存token
        $token = $this->redis->get(self::FEISHU_APP_TOKEN);
        if ($token) {
            return $token;
        }
        $url = 'https://open.feishu.cn/open-apis/auth/v3/app_access_token/internal/';
        $data = [
            'app_id' => $this->appid,
            'app_secret' => $this->appsecret
        ];
        $options = [];
        $options['timeout'] = 5;
        $options['headers']['Content-Type'] = 'application/json';
        $options['json'] = $data;

        $body = $this->request('POST', $url, $options);
        $body = json_decode($body);
        if ($body && $body->code == 0) {
            $token = $body->tenant_access_token;
            $expire = $body->expire;
            // 缓存token
            $this->redis->setex(self::FEISHU_APP_TOKEN, (int)$expire, $token);
            return $token;
        }
        return '';
    }

    private function getChat($name)
    {
        // 获取token
        $token = $this->getTenantAccessToken();
        $url = 'https://open.feishu.cn/open-apis/chat/v4/list';
        $options = [];
        $options['query'] = [];
        $options['timeout'] = 5;
        $options['headers']['Authorization'] = $this->generateAuthorization($token);

        $body = $this->request('GET', $url, $options);
        $this->debug('get chat', ['body' => $body]);
        $body = json_decode($body, true);
        if (!empty($body) && $body['code'] == 0) {
            foreach ($body['data']['groups'] as $group) {
                if ($group['name'] == $name) {
                    return $group;
                }
            }
        }
        return false;
    }

    /**
     * @param $method
     * @param $url
     * @param $options
     * @return string|\Symfony\Contracts\HttpClient\ResponseInterface
     */
    private function request($method, $url, $options)
    {
        /** @var \Symfony\Contracts\HttpClient\ResponseInterface $response */
        $response = $this->client->request($method, $url, $options);
        if ($this->client instanceof CurlHttpClient) {
            return $response->getContent();
        }
        return $response;
    }

    public function getLoginInfo($code)
    {
        $url = 'https://open.feishu.cn/open-apis/authen/v1/access_token';

        $data = [
            'app_access_token' => $this->getAppAccessToken(),
            'grant_type' => 'authorization_code',
            'code' => $code
        ];

        $token = $this->getTenantAccessToken();
        $options = [];
        $options['timeout'] = 5;
        $options['headers']['Content-Type'] = 'application/json';
        $options['headers']['Authorization'] = $this->generateAuthorization($token);
        $options['json'] = $data;

        $body = $this->request('POST', $url, $options);
        $body = json_decode($body, true);
        if (!empty($body) && $body['code'] == 0) {
            return $body['data'];
        }
        return false;
    }

}